/*
 * Copyright 2008-2011 Terry J. Gardner. All Rights Reserved.
 */

package com.ldapmaven;

import com.ldapmaven.annotations.Author;
import com.ldapmaven.annotations.CodeVersion;
import com.ldapmaven.annotations.Since;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentSkipListSet;

/**
 * Utility methods. This class cannot be instantiated.
 * <p/>
 * Includes methods for
 * <ul>
 * <li>Converting delimited string into a list of strings.</li>
 * <li>Creating a {@link List} in a type-safe way.</li>
 * <li>Creating a {@link Map} in a type-safe way.</li>
 * </ul>
 *
 * @author Terry.Gardner@UnboundID.COM
 * @since 1.0
 */
@Author("terry.gardner@unboundid.com")
@Since("01-Jan-2008")
@CodeVersion("1.2")
public final class CollectionUtils {

    /**
     * Private constructor that is not available for public use.
     */
    private CollectionUtils() {
    }

    /**
     * Given a {@link String} that consists of strings delimited by a
     * comma, returns a list wherein each member of the list was a string
     * delimited by a comma in the original string.
     *
     * @param csv A comma-separated list of strings.
     * @return Never returns {@code null}, that is, a list is always
     *         returned (but it might be empty.)
     */
    public static List<String> csvToList(final String csv) {
        final List<String> result = newArrayList();
        if(csv != null) {
            final StringTokenizer t = new StringTokenizer(csv,",");
            while(true) {
                if(!t.hasMoreTokens()) {
                    break;
                }
                final String token = t.nextToken();
                result.add(token);
            }
        }
        return Collections.unmodifiableList(result);
    }

    /**
     * Returns a new {@link ArrayList} in a type-safe way.
     *
     * @param <T> The type of each element of the list.
     * @return A new ArrayList.
     */
    public static <T> List<T> newArrayList() {
        return newArrayList(8);
    }

    /**
     * Returns a new {@link ArrayList} in a type-safe way.
     *
     * @param <T>  The type of each element of the list.
     * @param size The initial size of the list.
     * @return A new ArrayList.
     */
    public static <T> List<T> newArrayList(final int size) {
        return new ArrayList<T>(size);
    }

    /**
     * Returns a new {@link ConcurrentHashMap} in a type-safe way.
     *
     * @param <K> The type of the keys in the map.
     * @param <V> The type of values in the map.
     * @return A new ConcurrentHashMap.
     */
    public static <K, V> Map<K, V> newConcurrentHashMap() {
        return new ConcurrentHashMap<K, V>();
    }

    /**
     * Returns a new {@link EnumMap} in a type-safe way.
     *
     * @param <K>      The type of the keys in the map.
     * @param <V>      The type of values in the map.
     * @param keyClass the class object of the key type for this enum map.
     * @return A new enum map.
     */
    public static <K extends Enum<K>, V> Map<K, V> newEnumMap(final Class<K> keyClass) {
        return new EnumMap<K, V>(keyClass);
    }

    /**
     * Returns a new {@link HashMap} in a type-safe way.
     *
     * @param <K> The type of the keys in the map.
     * @param <V> The type of values in the map.
     * @return A new HashMap.
     */
    public static <K, V> Map<K, V> newHashMap() {
        return new HashMap<K, V>();
    }

    /**
     * Returns a new {@link HashSet} in a type-safe way.
     *
     * @param <E> The type of the objects in the set.
     * @param c   a collection of objects that will be used to create the
     *            set.
     * @return A new HashSet.
     */
    public static <E> Set<E> newHashSet(final Collection<E> c) {
        return new HashSet<E>(c);
    }

    /**
     * Returns a new {@link HashSet} in a type-safe way.
     *
     * @param <E> The type of the objects in the set.
     * @return A new HashSet.
     */
    public static <E> Set<E> newHashSet() {
        return new HashSet<E>();
    }

    /**
     * Returns a new {@link HashSet} in a type-safe way.
     *
     * @param <E> The type of the objects in the set.
     * @return A new HashSet.
     */
    public static <E> Set<E> newSortedSet() {
        return new ConcurrentSkipListSet<E>();
    }

}
